package com.zzj.controller;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.extra.servlet.ServletUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zzj.base.Result;
import com.zzj.entity.Invitation;
import com.zzj.entity.User;
import com.zzj.model.dto.LoginDTO;
import com.zzj.model.dto.WechatRegisterDTO;
import com.zzj.service.IInvitationService;
import com.zzj.service.IUserService;
import com.zzj.service.RedisService;
import com.zzj.utils.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Objects;
import java.util.UUID;

@RestController
@RequestMapping("/wechat")
public class WechatController {

    @Resource
    private WechatUtil wechatUtil;
    @Resource
    private IUserService userService;

    @Resource
    private IInvitationService invitationService;
    @Resource
    private RedisService redisService;
    @Resource
    private IPUtil ipUtil;

    @Transactional
    @PostMapping("login")
    public Result login(HttpServletRequest request, @RequestParam String code) {
        Result result = wechatUtil.getSessionKeyOrOpenId(code);
        if(result.getCode()==1){
            return result;
        }
        String openId = (String) result.getData();
        User user = userService.findUserByOpenId(openId);
        if (user==null) {
            return Result.error("用户未注册");
        }
        String ip = ipUtil.getIP(request);
        String address = ipUtil.getProvinceByIP(ip);
        user = userService.updateIpAddress(user.getId(), ip, address);

        String token = JWTUtil.generateToken(user.getUsername());
        String refreshToken = UUID.randomUUID().toString();
        redisService.setRefreshToken(token,refreshToken,user.getUsername());;

        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("token", token);
        hashMap.put("refreshToken", refreshToken);
        hashMap.put("userInfo", JSON.toJSONString(user));
        return Result.success(hashMap);
    }

    @Transactional
    @PostMapping("register")
    public Result register(@RequestBody @Validated WechatRegisterDTO in) {
        Result result = wechatUtil.getSessionKeyOrOpenId(in.getCode());
        if(result.getCode()==1){
            return result;
        }
        String openId = (String) result.getData();

        User user = new User();
        user.setAvatar(in.getAvatar());
        user.setUsername(in.getUsername());
        user.setOpenId(openId);

        if (userService.findUserByUsername(in.getUsername())!=null) {
            return Result.error("注册失败，用户名已存在");
        }
        if (in.getInvitationCode() != null && !Objects.equals(in.getInvitationCode(), "")) {

            String type = redisService.getTypeByInvitationCode(in.getInvitationCode());
            if(type==null){
               return Result.error("邀请码不存在");
            }
            user.setStatus(Integer.valueOf(type));
            redisService.removeInvitation(in.getInvitationCode());
            invitationService.use(in.getInvitationCode());
        }
        userService.save(user);
        return Result.success("注册成功");

    }

    @Transactional
    @PostMapping("/passwordLogin")
    public Result passwordLogin(HttpServletRequest request, @RequestBody @Validated LoginDTO in) throws Exception {
        String ip = ipUtil.getIP(request);
        String address = ipUtil.getProvinceByIP(ip);

        User user = userService.findUserByUsername(in.getUsername(), in.getPassword());
        if (user == null) {
            return Result.error("用户名或密码错误");
        }
        if (user.getOpenId()==null||user.getOpenId().isEmpty()) {
            return Result.error("用户不存在");
        }
        user = userService.updateIpAddress(user.getId(), ip, address);

        String token = JWTUtil.generateToken(in.getUsername());
        String refreshToken = UUID.randomUUID().toString();
        redisService.setRefreshToken(token,refreshToken,user.getUsername());
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("token", token);
        hashMap.put("refreshToken", refreshToken);
        hashMap.put("userInfo", JSON.toJSONString(user));
        return Result.success(hashMap);
    }
}
